﻿namespace Tomers.WPF.Localization
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Globalization;
    using System.Text;
    using System.Windows.Data;

    /// <summary>
    /// LanguageConverter class. Translates text.
    /// </summary>
    public class LanguageConverter : IValueConverter, IMultiValueConverter
    {
        #region Fields

        private string uid;
        private string vid;
        private object defaultValue;
        private bool isStaticUid;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the LanguageConverter class.
        /// </summary>
        /// <param name="uid">Uid.</param>
        /// <param name="vid">Vid.</param>
        /// <param name="defaultValue">Default value.</param>
        public LanguageConverter(string uid, string vid, object defaultValue)
        {
            this.uid = uid;
            this.vid = vid;
            this.defaultValue = defaultValue;
            this.isStaticUid = true;
        }

        #endregion

        #region Private methods

        private bool ShouldTranslateText
        {
            get { return string.IsNullOrEmpty(this.vid); }
        }

        #endregion

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            LanguageDictionary dictionary = ResolveDictionary();
            object translation = dictionary.Translate(uid, vid, defaultValue, targetType);
            return translation;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return Binding.DoNothing;
        }

        #endregion

        #region IMultiValueConverter Members

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                int parametersCount = this.isStaticUid ? values.Length - 1 : values.Length - 2;
                if (string.IsNullOrEmpty(this.uid))
                {
                    if (values[1] == null)
                    {
                        throw new ArgumentNullException("Uid must be provided as the first Binding element, and must not be null");
                    }
                    this.isStaticUid = false;
                    this.uid = values[1].ToString();
                    --parametersCount;
                }
                LanguageDictionary dictionary = ResolveDictionary();
                object translatedObject = dictionary.Translate(this.uid, this.vid, this.defaultValue, targetType);
                if (translatedObject != null && parametersCount != 0)
                {
                    object[] parameters = new object[parametersCount];
                    Array.Copy(values, values.Length - parametersCount, parameters, 0, parameters.Length);
                    try
                    {
                        translatedObject = string.Format(translatedObject.ToString(), parameters);
                    }
                    catch (Exception)
                    {
                        #region Trace
                        Debug.WriteLine(string.Format("LanguageConverter failed to format text {0}", translatedObject.ToString()));
                        #endregion
                    }
                }
                return translatedObject;
            }
            catch (Exception ex)
            {
                #region Trace
                Debug.WriteLine(string.Format("LanguageConverter failed to convert text: {0}", ex.Message));
                #endregion
            }
            return null;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            return new object[0];
        }

        #endregion

        #region Private static methods

        private static LanguageDictionary ResolveDictionary()
        {
            LanguageDictionary dictionary = LanguageDictionary.GetDictionary(
                LanguageContext.Instance.Culture);
            if (dictionary == null)
            {
                throw new InvalidOperationException(string.Format("Dictionary for language {0} was not found",
                    LanguageContext.Instance.Culture));
            }
            return dictionary;
        }

        #endregion
    }
}
